#if defined(ARCTIC)
#if (FEATURE_MODE == 0)
/**
 @file sys_at_npm.c

 @date 2021-6-8

 @version v1.0

 The file contains AT NPM APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sys_usw_common.h"
#include "drv_api.h"
#include "sys_usw_npm.h"


STATIC int32
_sys_at_npm_read_by_acc(uint8 lchip, uint32 index, void* ds)
{
    ds_t CpuReq;
    uint32 cmd = 0;
    uint32 loop = 0;
    uint32 count = 0;
    uint32 cpuReqDone = 0;

#if (SDK_WORK_PLATFORM == 1)
    cmd = DRV_IOR(DsOamTwampStats_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, ds));
    return CTC_E_NONE;
#endif

    sal_memset(&CpuReq, 0 , sizeof(ds_t));
    /*1. clear result*/
    cmd = DRV_IOW(DsOamTwampStatsRcResult_t, DsOamTwampStatsRcResult_rcDone_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &cpuReqDone));
    /*1. set request*/
    cmd = DRV_IOW(DsOamTwampStatsRcReq_t, DRV_ENTRY_FLAG);
    SetDsOamTwampStatsRcReq(V, rcValid_f, &CpuReq, 1);
    SetDsOamTwampStatsRcReq(V, rcAddr_f, &CpuReq, index);
    SetDsOamTwampStatsRcReq(V, clearOnRead_f, &CpuReq, 1);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &CpuReq));
    /*2. wait result done*/
    cmd = DRV_IOR(DsOamTwampStatsRcResult_t, DRV_ENTRY_FLAG);
    for (loop = 0; (loop < 2000) && !cpuReqDone; loop++)
    {
        for (count = 0; (count < 150) && !cpuReqDone; count++)
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
            cpuReqDone = GetDsOamTwampStatsRcResult(V, rcDone_f, ds);
        }

        if (cpuReqDone)
        {
            return CTC_E_NONE;
        }
        sal_task_sleep(1);
    }
    return CTC_E_HW_BUSY;
}


int32 sys_at_npm_get_stats_from_asic(uint8 lchip, void* p_session)
{
    uint32 tmp = 0;
    uint64 total_delay = 0;
    uint8  is_ntp_mode = 0;
    uint64 min_delay = 0;
    uint64 max_delay = 0;
    uint32 jitter = 0;
    uint32 far_min_jitter = 0;
    uint32 near_min_jitter = 0;
    uint32 two_way_min_jitter=0;
    uint32 cmd =0;
    DsOamTwampStats_m twamp_stats;

    sys_npm_lite_session_t* npm_lite_session = NULL;
    npm_lite_session = (sys_npm_lite_session_t*)p_session;

    is_ntp_mode = npm_lite_session->ts_format;
    CTC_ERROR_RETURN(_sys_at_npm_read_by_acc(lchip,npm_lite_session->twamp_idx,(void*)&twamp_stats));

    npm_lite_session->session_stats.rx_pkts_all += GetDsOamTwampStats(V, rxPkts_f, &twamp_stats);
    npm_lite_session->lite_stats.rx_fcl_all += GetDsOamTwampStats(V, rxFcl_f, &twamp_stats);
    npm_lite_session->session_stats.tx_pkts_all += GetDsOamTwampStats(V, txFcb_f, &twamp_stats);
    npm_lite_session->session_stats.disorder_pkts += GetDsOamTwampStats(V, seqDisorderCnt_f, &twamp_stats);

    tmp = GetDsOamTwampStats(V, totalDTs_f , &twamp_stats);
    total_delay = is_ntp_mode ? (((tmp&0x38000000) >> 27)*1000000000 + ((tmp&0x7FFFFFF) << 5)*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU) : ((((uint64)tmp & 0x38000000) << 5) + ((tmp&0x7FFFFFF) << 5));
    npm_lite_session->session_stats.total_delay_all += total_delay;

    jitter = SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_2_maxJitter_f, &twamp_stats));
    npm_lite_session->lite_stats.two_way_max_jitter = (npm_lite_session->lite_stats.two_way_max_jitter < jitter)? jitter : npm_lite_session->lite_stats.two_way_max_jitter;
    if (npm_lite_session->synced)
    {
        jitter = SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_1_maxJitter_f, &twamp_stats));
        npm_lite_session->lite_stats.far_max_jitter = (npm_lite_session->lite_stats.far_max_jitter < jitter)? jitter : npm_lite_session->lite_stats.far_max_jitter;
        npm_lite_session->lite_stats.far_total_jitter_all += SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_1_totalJitter_f, &twamp_stats));
        far_min_jitter = SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_1_minJitter_f, &twamp_stats));
    }
    jitter = SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_0_maxJitter_f, &twamp_stats));
    npm_lite_session->lite_stats.near_max_jitter = (npm_lite_session->lite_stats.near_max_jitter < jitter)? jitter : npm_lite_session->lite_stats.near_max_jitter;

    npm_lite_session->lite_stats.two_way_total_jitter_all += SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_2_totalJitter_f, &twamp_stats));
    npm_lite_session->lite_stats.near_total_jitter_all += SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_0_totalJitter_f, &twamp_stats));

    tmp = GetDsOamTwampStats(V, minDelay_f , &twamp_stats);
    min_delay = is_ntp_mode ? (((tmp&0x38000000) >> 27)*1000000000 + ((tmp&0x7FFFFFF) << 5)*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU) : ((((uint64)tmp & 0x38000000) << 5) + ((tmp&0x7FFFFFF) << 5));

    two_way_min_jitter = SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_2_minJitter_f, &twamp_stats));
    near_min_jitter = SYS_NPM_TS_TO_NS(is_ntp_mode, GetDsOamTwampStats(V, array_0_minJitter_f, &twamp_stats));
    if (min_delay)/*min_delay=0, means stats has been cleared on read*/
    {
        npm_lite_session->session_stats.min_delay = (npm_lite_session->session_stats.min_delay > min_delay)? min_delay : npm_lite_session->session_stats.min_delay;
        npm_lite_session->lite_stats.two_way_min_jitter = (npm_lite_session->lite_stats.two_way_min_jitter > two_way_min_jitter)? two_way_min_jitter : npm_lite_session->lite_stats.two_way_min_jitter;
        npm_lite_session->lite_stats.far_min_jitter = (npm_lite_session->lite_stats.far_min_jitter > far_min_jitter)? far_min_jitter : npm_lite_session->lite_stats.far_min_jitter;
        npm_lite_session->lite_stats.near_min_jitter = (npm_lite_session->lite_stats.near_min_jitter > near_min_jitter)? near_min_jitter : npm_lite_session->lite_stats.near_min_jitter;
    }

    tmp = GetDsOamTwampStats(V, maxDelay_f , &twamp_stats);
    max_delay = is_ntp_mode ? (((tmp&0x38000000) >> 27)*1000000000 + ((tmp&0x7FFFFFF) << 5)*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU) : ((((uint64)tmp & 0x38000000) << 5) + ((tmp&0x7FFFFFF) << 5));

    npm_lite_session->session_stats.max_delay = (npm_lite_session->session_stats.max_delay < max_delay)? max_delay : npm_lite_session->session_stats.max_delay;
    npm_lite_session->synced =1;
    if (1 == SDK_WORK_PLATFORM)
    {
        sal_memset(&twamp_stats, 0, sizeof(twamp_stats));
        cmd = DRV_IOW(DsOamTwampStats_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, npm_lite_session->twamp_idx, cmd, &twamp_stats);
    }
	return CTC_E_NONE;

}

int32
sys_at_npm_isr_sync_stats(uint8 lchip, uint32 intr, void* p_data)
{
    uint32 intr_bmp[16]={0};
    uint32 cmd = 0;
    int32 ret = 0;
    uint16 session_id = 0;
    sys_npm_lite_session_t* npm_lite_session = NULL;
    uint16 do_intr_num = sizeof(intr_bmp)*BITS_NUM_OF_BYTE;

    NPM_LOCK(lchip);

    cmd = DRV_IOR(OamTwampIntrBitmap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, intr_bmp), ret, end);

    for (session_id = 0; session_id < do_intr_num; session_id++)
    {

        npm_lite_session = (sys_npm_lite_session_t*)ctc_vector_get(g_npm_master[lchip]->session_lite, session_id);
        if (npm_lite_session && (CTC_BMP_ISSET(intr_bmp, npm_lite_session->twamp_idx)))
        {
            CTC_ERROR_GOTO(sys_at_npm_get_stats_from_asic(lchip, (void*)npm_lite_session), ret, end);
        }
    }

    cmd = DRV_IOW(OamTwampIntrBitmap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, intr_bmp), ret, end);/*Write 1 clear*/

end:
    NPM_UNLOCK(lchip);
	return ret;
}



#endif
#endif

